package label

import (
	"context"
	"gitee.com/bobo-rs/idea-space-framework/framework/dao"
	"gitee.com/bobo-rs/idea-space-framework/framework/model"
	"gitee.com/bobo-rs/idea-space-framework/framework/model/entity"
	"gitee.com/bobo-rs/idea-space-framework/pkg/encrypt"
	"gitee.com/bobo-rs/idea-space-framework/pkg/utils"
	"github.com/gogf/gf/v2/errors/gerror"
	"github.com/gogf/gf/v2/frame/g"
	"strings"
)

// SaveLabelIdx 保存标签索引信息
func (l *sLabel) SaveLabelIdx(ctx context.Context, cid, cType uint, value string) error {
	// 拆解标签值
	idxValues := l.LabelIdxValueHash(strings.Split(value, `-`))
	if len(idxValues) == 0 {
		return gerror.New(`标签值不存在`)
	}
	// 获取标签值索引MAP
	idxMap, _ := l.ProcessLabelIdxHashAndIdMap(ctx, cid, cType)
	// 初始化索引标签
	idxes := make([]entity.LabelIdx, 0)
	for _, idx := range idxValues {
		// 存在无需处理
		if _, ok := idxMap[idx.Hash]; ok {
			delete(idxMap, idx.Hash)
			continue
		}
		idxes = append(idxes, entity.LabelIdx{
			CorrelateId:   cid,
			CorrelateType: cType,
			LabelValue:    idx.Value,
			LabelHash:     idx.Hash,
		})
	}
	// 已存在无需更新
	if len(idxes) == 0 {
		return nil
	}
	// 删除不存在标签索引
	_ = l.afterDeleteSaveLabelIdx(ctx, cid, cType, idxMap)
	// 保存数据
	_, err := dao.LabelIdx.Ctx(ctx).Save(idxes)
	return err
}

// DeleteLabelIdx 删除标签索引
func (l *sLabel) DeleteLabelIdx(ctx context.Context, cid, cType uint, hash ...string) error {
	where := g.Map{
		dao.LabelIdx.Columns().CorrelateId:   cid,
		dao.LabelIdx.Columns().CorrelateType: cType,
	}
	if len(hash) > 0 {
		where[dao.LabelIdx.Columns().LabelHash] = hash
	}
	// 是否存在
	res, _ := l.CheckLabelIdxExists(ctx, where)
	if res == false {
		return nil
	}
	_, err := dao.LabelIdx.Ctx(ctx).Where(where).Delete()
	if err != nil {
		return gerror.Wrapf(err, `删除索引失败[%s]，请重试`, err.Error())
	}
	return nil
}

// LabelIdxValueHash 生成标签Hash值和标签值
func (l *sLabel) LabelIdxValueHash(values []string) []model.IdxValueHashItem {
	// 生成标签集合
	slices := utils.GenCombinationsString(values, `-`)
	if len(slices) == 0 {
		return nil
	}
	idxValues := make([]model.IdxValueHashItem, 0, len(slices))
	for _, value := range slices {
		idxValues = append(idxValues, model.IdxValueHashItem{
			Value: value,
			Hash:  encrypt.NewM().MustEncryptString(value),
		})
	}
	return idxValues
}

// GenIdxHash 生成标签索引Hash值
func (l *sLabel) GenIdxHash(values []string) []string {
	// 生成标签集合
	slices := utils.GenCombinationsString(values, `-`)
	if len(slices) == 0 {
		return nil
	}

	// 处理生成Hash值集合
	hasher := make([]string, 0, len(slices))
	for _, value := range slices {
		hasher = append(hasher, encrypt.NewM().MustEncryptString(value))
	}
	return hasher
}

// GenHash 生成Hash值
func (l *sLabel) GenHash(value string) string {
	if len(value) == 0 {
		return ""
	}
	return encrypt.NewM().MustEncryptString(value)
}

// afterDeleteSaveLabelIdx 保存标签索引-后置处理删除不存在的标签索引
func (l *sLabel) afterDeleteSaveLabelIdx(ctx context.Context, cid, cType uint, hashMap map[string]uint) error {
	if len(hashMap) == 0 {
		return nil
	}
	hasher := make([]string, 0, len(hashMap))
	for key := range hashMap {
		hasher = append(hasher, key)
	}
	// 删除数据
	return l.DeleteLabelIdx(ctx, cid, cType, hasher...)
}
